/*
 * EmployeeWindowController.java
 * 
 * Copyright (c) 2008, Marshall Scorcio, Ralph Holzmann, 
 *                     Stewart Sweet, Tyler Hoersch, Jeffery Van Handel
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the University of Wisconsin Oshkosh nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' AND 
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 */
  
import java.util.*;
 
public class EmployeeWindowController implements ViewEventListener
{
    private EmployeeWindow employeeWindow;
    private Vector<Employee> employees;
    
    public EmployeeWindowController()
    {
        employeeWindow = new EmployeeWindow();
        employeeWindow.addViewEventListener(this);
        employeeWindow.setVisible(true);
    }
    
    public void setEmployees(Vector<Employee> employees)
    {
        this.employees = employees;
        loadEmployeeList();
    }
    
    public void viewEventOccurred(ViewEvent event)
    {
        if (event.toString().equals("EmployeeSelectionChanged"))
        {
            selectEmployee();
        }
        else if (event.toString().equals("AddEmployee"))
        {
            addEmployee();
        }
        else if (event.toString().equals("DeleteEmployee"))
        {
            deleteEmployee();
        }
        else if (event.toString().equals("AddRequestedDayOff"))
        {
            addRequestedDayOff((DateChooser) event.getSource());
        }
        else if (event.toString().equals("RemoveRequestedDayOff"))
        {
            removeRequestedDayOff();
        }
        else if (event.toString().equals("Apply"))
        {
            applyChanges();
        }
    }
    
    private void loadEmployeeList()
    {
        String[] employeeNames = new String[employees.size()];
        for (int i = 0; i < employees.size(); i++)
        {
            employeeNames[i] = employees.get(i).getName();
        }  
        
        employeeWindow.setEmployees(employeeNames);
    }
    
    private void selectEmployee()
    {
        Employee employee = findEmployee(employeeWindow.getSelectedEmployee());
        
        if (employee != null)
        {   
            employeeWindow.resetPropertiesPanel();
            employeeWindow.setEmployeeInformation(employee.getName(), employee.getID(), employee.getEmail(),
                                                  employee.getPosition(), employee.getExperienceLevel());
            loadRequestedDaysOff(employee);
            loadDailyAvailability(employee);
        }
    }
    
    private void addEmployee()
    {        
        employees.add(new Employee("New Employee", "", "", "", 0));
        employeeWindow.addEmployee("New Employee");
        employeeWindow.setSelectedEmployee(employees.size() - 1);
    }
    
    private void deleteEmployee()
    {   
        String name = employeeWindow.getSelectedEmployee();
        
        for (int i = 0; i < employees.size(); i++)
        {
            if (employees.get(i).getName().equals(name))
            {
                employees.remove(i);
            }
        }
        
        employeeWindow.removeEmployee(name);
        employeeWindow.unselectCurrentEmployee();
        
        EmployeeSerializer.saveEmployees(employees);
    }
    
    private void addRequestedDayOff(DateChooser dateChooser)
    {
        employeeWindow.addRequestedDayOff(dateChooser.getFormattedDate(), dateChooser.getFormattedTime(), dateChooser.getReason());
    }
       
    private void removeRequestedDayOff()
    {
        employeeWindow.removeRequestedDayOff(employeeWindow.getSelectedRequestedDayOff());
    }
        
    private void saveRequestedDaysOff(Employee employee)
    {
        String[][] requestedDaysOff = employeeWindow.getRequestedDaysOff();
        
        EmployeeAvailability employeeAvailibility = employee.getAvailability();
        
        employeeAvailibility.clearRequestedDaysOff();
         
        for (int i = 0; i < requestedDaysOff.length; i++)
        {
            RequestedDayOff requestedDayOff;

            String date = requestedDaysOff[i][0];
            String time = requestedDaysOff[i][1];
            String reason = requestedDaysOff[i][2];
            
            requestedDayOff = new RequestedDayOff(date, reason);
            requestedDayOff.addTimeBlock(time);
           
            employeeAvailibility.addRequestedDayOff(requestedDayOff); 
        }
    }
    
    private void loadRequestedDaysOff(Employee employee)
    {
        EmployeeAvailability employeeAvailability = employee.getAvailability();
        Vector<RequestedDayOff> requestedDaysOff = employeeAvailability.getRequestedDaysOff();
        
        employeeWindow.removeAllRequestedDaysOff();
        
        for (int i = 0; i < requestedDaysOff.size(); i++)
        {
            RequestedDayOff requestedDayOff = requestedDaysOff.elementAt(i);
            String date = requestedDayOff.getDate();
            String time = requestedDayOff.getTimeBlocks().elementAt(0).toString();
            String reason = requestedDayOff.getReason();
            
            employeeWindow.addRequestedDayOff(date, time, reason);
        }
    }
    
    private void saveDailyAvailability(Employee employee)
    {
        EmployeeAvailability employeeAvailability = employee.getAvailability();
      
        String[] availability = employeeWindow.getAvailability();
        boolean[] availableAllDay = employeeWindow.isAvailableAllDaySelected();
        boolean[] notAvailable = employeeWindow.isNotAvailableSelected();
        
        employeeAvailability.clearWeeklyAvailability();
        
        for (int i = 0; i < availability.length; i++)
        {
            Day day = new Day(i);
            
            if (availableAllDay[i])
            {
                day.addTimeBlock(0, 0, 23, 59);
            }
            else if (notAvailable[i] == false)
            {
                day.addTimeBlock(new TimeBlock(availability[i]));
            }
        
            employeeAvailability.addDailyAvailability(day);
        }
    }
    
    private void loadDailyAvailability(Employee employee)
    {
        EmployeeAvailability employeeAvailability = employee.getAvailability();
        Vector<Day> weeklyAvailability = employeeAvailability.getWeeklyAvailability();
        String[] availability = new String[7];
        
        employeeWindow.resetAvailability();
        
        for (int i = 0; i < 7; i++)
        {
            Day day = employeeAvailability.getDailyAvailabilityFor(i);
            
            if (day.getNumberOfTimeBlocks() != 0)
            {
                availability[i] = day.getTimeBlocks().elementAt(0).toString();
            }
            else
            {   
                availability[i] = "";
            }
        }
        
        employeeWindow.setAvailability(availability);
    }
            
    private void applyChanges()
    {
        Employee employee = findEmployee(employeeWindow.getSelectedEmployee());
     
        String[] employeeInformation = employeeWindow.getEmployeeInformation();
              
        employee.setName(employeeInformation[0]);
        employee.setID(employeeInformation[1]);
        employee.setEmail(employeeInformation[2]);
        employee.setPosition(employeeInformation[3]);
        employee.setExperienceLevel(Integer.parseInt(employeeInformation[4]));
        
        saveDailyAvailability(employee);
        saveRequestedDaysOff(employee);
        
        loadEmployeeList();
        
        employeeWindow.setSelectedEmployee(employees.indexOf(employee));

        EmployeeSerializer.saveEmployees(employees);
    }
    
    private Employee findEmployee(String name)
    {
        Employee employee = null;
        
        for (int i = 0; i < employees.size(); i++)
        {
            if (employees.get(i).getName().equals(name))
            {
                employee = employees.get(i);
            }
        }

        return employee;
    }
}

